#pragma once
// Copyright (c) 2015 Tony Kirke. License MIT  (http://www.opensource.org/licenses/mit-license.php)
// from directory: spuc_double_templates
#include <spuc/spuc_types.h>
#include <iostream>
#include <fstream>
#include <spuc/complex.h>
#include <spuc/quantiser.h>
#include <spuc/mixed_type.h>
namespace SPUC {
//! \file
//! \brief  Template Class for 1st Order high pass IIR filter from S-domain transformation
//
//! \brief  Template Class for 1st Order high pass IIR filter from S-domain transformation
//
//!   The filter is the first order high pass digital filter
//!   generated by the bilinear transform of a first order analog filter.
//!   <p>\f$ H(s) = \frac{s}{(s+A)} \f$
//!   <p>\f$ H(z) = \frac{A*(1-z^-1)}{((1+A)+(1-A)z^-1)} \f$ where A is real
//! \author Tony Kirke
//! \ingroup double_templates iir
template <class Numeric, class Coeff = float_type> class iir_hpf {
 protected:
  Coeff gain;
  Coeff a;
  Numeric out;
  Numeric previous_out;
  Numeric previous_in;
  quantiser<Numeric> Q;

 public:
  iir_hpf(Coeff A = 0, long b = 0) : Q(b) {
    gain = (1 - A) / (1 + A);
    a = 1.0 / (1 + A);
    reset();
  }
  void set_coeff(Coeff A) { gain = A; }
  Coeff get_a0() { return (gain); }
  Coeff get_b0() { return (a); }
  //! Print out coefficients
  void print() {
    std::cout << "IIR B0 = " << a << ", ";
    std::cout << "A0 = " << gain << "\n";
  }
  //! Input new sample and calculate output
  Numeric clock(Numeric input) {
    typename mixed_type<Numeric, Coeff>::dtype sum;
    // Shift previous outputs and calculate new output */
    //	out = gain*previous_out + (1-gain)*input;
    sum = gain * previous_out + a * (input - previous_in);
    out = Q(sum);
    previous_out = out;
    previous_in = input;
    return (out);
  }
  //! Reset
  void reset() { previous_in = previous_out = out = (Numeric)0; }
};
}  // namespace SPUC
